#include "../include/pthreadpool.h"
#include "../include/server.h"
#include "../include/taskqueue.h"
#include "../include/func.h"
#include "../include/log.h"
#include "../include/serverpasswd.h"

void pthreadpool_creat(pthreadpool_t* q)
{
    q->index=(pthread_t*)calloc(PTHREAD_NUM,sizeof(pthread_t));
    q->pthreadnum = PTHREAD_NUM;
    pthread_mutex_init(&q->mutex, NULL);
    queue_init(&q->queue,TASK_MAXNUM);
}

void pthreadpool_destroy(pthreadpool_t* p)
{ 
    queue_destroy(&p->queue);
    free(p->index);
}

void pthreadpool_start(pthreadpool_t *p)
{
    for(int i=0;i< p->pthreadnum;i++){
        pthread_create(&p->index[i],NULL,pthreadpool_handle,p);
    }
}

//接收指令
cmd_t *recvCmd(int peerfd)
{
    cmd_t *cmdBuff = (cmd_t *)malloc(sizeof(cmd_t));
    memset(cmdBuff, 0, sizeof(cmd_t));
    int ret = recv(peerfd, cmdBuff, sizeof(cmd_t), MSG_WAITALL);
    printf("%d\n",cmdBuff->cmd);
    if(ret <= 0){
        printf("connect is close.\n");
        return NULL;
    }

    return cmdBuff;
}

void* pthreadpool_handle(void* arg)
{
    printf("pthread id %ld is running\n",pthread_self());
    taskqueue_t* t=(taskqueue_t*)&((pthreadpool_t*)arg)->queue;
    while(1){
        int fd=dequeue(t);
        printf("fd : %d client has been recv by thread %ld!\n",fd, pthread_self());

        ///////////////////////////////////
        DatabaseInit_server();
        //数据库已经准备就绪
        //接收指令 注册/登录
        while(1)
        {
            //等待接收客户端登录/注册指令
            char ch=0;
            int ret1;
            ret1=66;
            int ret=recv(fd,&ch,1,MSG_WAITALL);
            if(ch=='e')
            {
                break;
            }
            if(ret<=0)
            {
                printf("%d peerfd disconnected!\n",fd);
                return 0;
            }
            char registusername[66]={0};
            switch(ch)
            {
            case 's':
                showTable("user");
                break;
            case 'r':
                //注册
                //char registusername[66]={0};
                ret1=mysqlRegisterUsername(fd,registusername);
                if(ret1)
                {
                    mysqlRegisterPasswd(fd,registusername);
                }
                break;
            }
        }
        //////////////////////////////
        char buf[20]={0};
        memset(buf,0,sizeof(buf));
        char* username = userLogin(fd, buf);
        if(username ==NULL) break;
        CMD_LOG(*(pthreadpool_t*)arg,buf,LOG_INFO,LOG_INFO," USER LOGIN");
        if(fd != -1){
            while(true){
                int ret;
                cmd_t* cmd;
again:
                ret = 1;
                cmd = recvCmd(fd);
                if(cmd == NULL){
                    close(fd);
                    break;
                }
                switch(cmd->cmd){
                case CMD_TYPE_EXIT: 
                    {
                        CMD_LOG(*(pthreadpool_t*)arg,buf,LOG_INFO,LOG_INFO," USER EXIT");
                        ret = 0;
                    }break;
                case CMD_TYPE_CD:
                    ret=cd_command(fd, cmd);
                    if(ret>0) CMD_LOG(*(pthreadpool_t*)arg,buf,LOG_INFO,LOG_INFO," USER CD");
                    free(cmd);
                    goto again;
                case CMD_TYPE_LS:
                    ret=ls_command(fd, cmd);
                    if(ret>0) CMD_LOG(*(pthreadpool_t*)arg,buf,LOG_INFO,LOG_INFO," USER LS");
                    break;
                case CMD_TYPE_LL:
                    ret=ll_command(fd,cmd);
                    if(ret>0) CMD_LOG(*(pthreadpool_t*)arg,buf,LOG_INFO,LOG_INFO," USER LL");
                    break;
                case CMD_TYPE_PWD:
                    ret=pwd_command(fd, cmd);
                    if(ret>0) CMD_LOG(*(pthreadpool_t*)arg,buf,LOG_INFO,LOG_INFO," USER PWD");
                    ERROR_CHECK(ret, -1 ,"pwd_command");
                    break;
                case CMD_TYPE_GETS:
                    //ret=gets_filename_command(fd,cmd);
                    ret=getsfileplus_command(fd,cmd->args[0].arg);
                    if(ret>0) CMD_LOG(*(pthreadpool_t*)arg,buf,LOG_INFO,LOG_INFO," USER GETSFILE");
                    break;
                case CMD_TYPE_PUTS:
                    ret=puts_filename_command(fd,cmd);
                    if(ret>0) CMD_LOG(*(pthreadpool_t*)arg,buf,LOG_INFO,LOG_INFO," USER PUTSFILE");
                    free(cmd);
                    goto again;
                case CMD_TYPE_MV:
                    ret=mv_command(fd, cmd);
                    if(ret>0) CMD_LOG(*(pthreadpool_t*)arg,buf,LOG_INFO,LOG_INFO," USER MV");
                    free(cmd);
                    goto again;
                case CMD_TYPE_CP:
                    ret=cp_command(fd, cmd);
                    if(ret>0) CMD_LOG(*(pthreadpool_t*)arg,buf,LOG_INFO,LOG_INFO," USER CP");
                    free(cmd);
                    goto again;
                case CMD_TYPE_RM:
                    ret=rm_command(fd,cmd);
                    if(ret>0) CMD_LOG(*(pthreadpool_t*)arg,buf,LOG_INFO,LOG_INFO," USER RM");
                    free(cmd);
                    goto again;
                case CMD_TYPE_MKDIR:
                    ret=mkdir_command(fd,cmd);
                    if(ret>0) CMD_LOG(*(pthreadpool_t*)arg,buf,LOG_INFO,LOG_INFO," USER MKDIR");
                    break;
                default: ret = -1; break; 
                }
                if(ret==-1) 
                    send(fd,"ERROR ORDER!",13,MSG_WAITALL);
                else if(ret==0){
                    close(fd);
                    break;
                }
                free(cmd);
            }
        }
    }
    printf("pthread %ld is exiting!\n",pthread_self());
    pthread_exit(0);
}

